import { getConfig } from "@/common/config";
import { ReportDataTypes } from "@/common/types";
import {
  postBehaviorsBasicbehaviors,
  postBehaviorsClickbehaviors,
  postBehaviorsPageskipbehaviors,
  postBehaviorsRoutingskipbehaviors,
  postErrorsJavascripterrors,
  postErrorsPromiseerrors,
  postErrorsResourceerrors,
  postPerformancesBasicindicators,
  postPerformancesInterfaceindicators,
  postPerformancesResourceindicators,
  postReplayReport,
  Replay,
} from "@/common/utils/apis";
import { getTimeStamp } from "@/common/utils/datas";
import { onBeforeUnload } from "@/common/utils/events";
import { eventsMatrix } from "@/monitoring/recall/replay";
// 缓存
const cacheMapSize = getConfig().cacheMapSize;
const cacheMap = new Map<string, any[]>([]);
cacheMap.set("BasicIndicator", []);
cacheMap.set("InterfaceIndicator", []);
cacheMap.set("ResourceIndicator", []);
cacheMap.set("ResourceError", []);
cacheMap.set("JavaScriptError", []);
cacheMap.set("PromiseError", []);
// cacheMap.set("VueError", []);
cacheMap.set("BasicBehavior", []);
cacheMap.set("ClickBehavior", []);
cacheMap.set("PageSkipBehavior", []);
cacheMap.set("RoutingSkipBehavior", []);
let count = 0;

// 上报全部数据
export const reportAll = () => {
  for (const key of cacheMap.keys()) {
    if (cacheMap.get(key)!.length > 0) {
      // 上报对应的监控信息
      // key 对应的是 ReportDataTypes 的联合类型
      realTimeReport(key as keyof ReportDataTypes, cacheMap.get(key)!);
      cacheMap.set(key, []);
    }
  }
  count = 0;
};

// 即将离开当前页面(刷新或关闭)时执行
onBeforeUnload(reportAll);

// 每间隔一段时间进行上报全部数据
setInterval(reportAll, getConfig().reportTimeInterval);

/**
 * 上报的具体实现
 * @param monitorName 监控的名称
 * @param data
 */
export const realTimeReport = <K extends keyof ReportDataTypes>(
  monitorName: K,
  data: ReportDataTypes[K][]
) => {
  switch (monitorName) {
    case "BasicIndicator":
      postPerformancesBasicindicators({
        requestBody: data as ReportDataTypes["BasicIndicator"][],
      }).catch((e: any) => {
        console.log(e);
      });
      break;
    case "InterfaceIndicator":
      postPerformancesInterfaceindicators({
        requestBody: data as ReportDataTypes["InterfaceIndicator"][],
      }).catch((e: any) => {
        console.log(e);
      });
      break;
    case "ResourceIndicator":
      postPerformancesResourceindicators({
        requestBody: data as ReportDataTypes["ResourceIndicator"][],
      }).catch((e: any) => {
        console.log(e);
      });
      break;
    case "ResourceError":
      postErrorsResourceerrors({
        requestBody: data as ReportDataTypes["ResourceError"][],
      }).catch((e: any) => {
        console.log(e);
      });
      break;
    case "JavaScriptError":
      postErrorsJavascripterrors({
        requestBody: data as ReportDataTypes["JavaScriptError"][],
      }).catch((e: any) => {
        console.log(e);
      });
      break;
    case "PromiseError":
      postErrorsPromiseerrors({
        requestBody: data as ReportDataTypes["PromiseError"][],
      }).catch((e: any) => {
        console.log(e);
      });
      break;
    case "VueError":
      // postErrorsVueerrors({
      //   requestBody: data as ReportDataTypes["VueError"][],
      // }).catch((e: any) => {
      //   console.log(e);
      // });
      break;
    case "BasicBehavior":
      postBehaviorsBasicbehaviors({
        requestBody: data as ReportDataTypes["BasicBehavior"][],
      }).catch((e: any) => {
        console.log(e);
      });
      break;
    case "ClickBehavior":
      postBehaviorsClickbehaviors({
        requestBody: data as ReportDataTypes["ClickBehavior"][],
      }).catch((e: any) => {
        console.log(e);
      });
      break;
    case "PageSkipBehavior":
      postBehaviorsPageskipbehaviors({
        requestBody: data as ReportDataTypes["PageSkipBehavior"][],
      }).catch((e: any) => {
        console.log(e);
      });
      break;
    case "RoutingSkipBehavior":
      postBehaviorsRoutingskipbehaviors({
        requestBody: data as ReportDataTypes["RoutingSkipBehavior"][],
      }).catch((e: any) => {
        console.log(e);
      });
      break;
    default:
      throw new Error(`Unknown monitorName: ${monitorName}`);
  }
};

/**
 *
 * @param monitorName  监控名称
 * @param data 上报的数据
 */
export const stagingReport = <K extends keyof ReportDataTypes>(
  monitorName: K,
  data: ReportDataTypes[K]
) => {
  const cacheItems = cacheMap.get(monitorName) as any[];
  cacheItems.push(data);
  count++;
  if (count >= cacheMapSize) {
    reportAll();
  }
  const array = ["ResourceError", "JavaScriptError", "PromiseError"];
  if (array.find((name) => name === monitorName)) {
    // 错误信息,开始上传
    const len = eventsMatrix.length;
    const events = eventsMatrix[len - 2].concat(eventsMatrix[len - 1]);
    // 上传事件 events
    let replay: Replay = {
      eventId: data.eventId,
      appId: data.appId,
      time: getTimeStamp(),
      userId: data.userID,
      events,
    };
    postReplayReport({ requestBody: replay }).catch((e: any) => {
      console.log(e);
    });
  }
};
